package com.zh.webflux.exception;

import com.alibaba.fastjson.JSON;
import com.zh.webflux.common.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 全局异常处理
 */
@Slf4j
@Component
@ControllerAdvice
public final class MyGlobalExceptionHandler implements ErrorWebExceptionHandler {
    public MyGlobalExceptionHandler() {
        log.info("[MyGlobalExceptionHandler] constructor ...");
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        System.out.println("全局异常处理.... " + ex.getMessage());
        ServerHttpResponse response = exchange.getResponse();

        HttpStatus status;

        if (ex instanceof NotFoundException) {
            status = HttpStatus.NOT_FOUND;
        } else if (ex instanceof IllegalArgumentException) {
            status = HttpStatus.BAD_REQUEST;
        } else if (ex instanceof OperationDeniedException) {
            status = HttpStatus.FORBIDDEN;
        } else if (ex instanceof AuthenticationException) {
            status = HttpStatus.UNAUTHORIZED;
        } else if (ex instanceof ServiceException) {
            //业务逻辑异常，返回http status 200。这是可预知的异常，一般无需处理
            status = HttpStatus.OK;
        } else {
            //其他不可预知的异常错误。通常是服务端严重的异常需要人工处理
            status = HttpStatus.INTERNAL_SERVER_ERROR;
            ex.printStackTrace();
        }

        response.setStatusCode(status);

        String json = JSON.toJSONString(ApiResult.fail(ex.getMessage()));
        return response.writeWith(Mono.just(response.bufferFactory().wrap(json.getBytes())));
    }
}
